using System.Collections;
using System.Collections.Generic;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.Rendering;

namespace DT.URP.Div
{
    //定义一个相机渲染器
    public class DTCameraRenderer
    {
        ScriptableRenderContext context;
        Camera camera;
        protected virtual string bufferName => $"{camera.name}[{camera.tag}] Render";
        CommandBuffer buff = new CommandBuffer();
        CullingResults cullingResults;
        static ShaderTagId unlitShaderTagId = new ShaderTagId("SRPDefaultUnlit"); //ForwardLit SRPDefaultUnlit
        static ShaderTagId forwardShaderTagId = new ShaderTagId("UniversalForward");

        public void Render(ScriptableRenderContext context, Camera camera)
        {
            this.context = context;
            this.camera = camera;
            buff.name = bufferName;
            if (this.camera == null)
            {
                Debug.LogError("相机为空");
                return;
            }
            if (!Cull())
            {
                return;
            }
            Setup();

            DrawVisibleGeometry();
            // DrawVisibleTransparentGeometry();
            DrawBackground();
            Submit();
        }

        void Setup()
        {
            context.SetupCameraProperties(camera);
            
            CameraClearFlags flags = camera.clearFlags;
            buff.ClearRenderTarget(flags <= CameraClearFlags.Depth,
                                   flags == CameraClearFlags.Color,
                                   flags == CameraClearFlags.Color ? camera.backgroundColor.linear : Color.clear);

            buff.BeginSample(bufferName);
            ExecuteBuffer();
        }
        void Submit()
        {
            buff.EndSample(bufferName);
            ExecuteBuffer();
            context.Submit();
        }
        void ExecuteBuffer()
        {
            context.ExecuteCommandBuffer(buff);
            buff.Clear();
        }

        bool Cull()
        {
            if (camera.TryGetCullingParameters(out ScriptableCullingParameters cullingParameters))
            {
                cullingResults = context.Cull(ref cullingParameters);
                return true;
            }
            return false;
        }

        void DrawBackground()
        {
            
        }
        /// <summary>
        /// 绘制可见的不透明物体
        /// </summary>
        void DrawVisibleGeometry()
        {
            // 绘制不透明物体
            // 创建一个排序设置对象，用于指定渲染对象的排序规则，这里使用相机作为参考，按照不透明物体的通用排序标准进行排序
            var sortingSettings = new SortingSettings(camera)
            {
                // 设置排序标准为通用的不透明物体排序规则
                criteria = SortingCriteria.CommonOpaque
            };

            // 创建一个绘制设置对象，用于指定渲染时使用的 Shader Pass 标签和排序设置
            var drawingSettings = new DrawingSettings(
                // 指定使用未光照着色器的 Shader Pass 标签，也可以替换为 forwardShaderTagId 使用前向渲染的 Shader Pass 标签
                forwardShaderTagId,  //unlitShaderTagId,//
                sortingSettings
            );

            // 创建一个过滤设置对象，用于指定渲染队列的范围，这里设置为渲染所有队列的对象
            var filterSettings = new FilteringSettings(
                RenderQueueRange.all
            );

            // 使用 ScriptableRenderContext 绘制经过剔除后的渲染对象，根据绘制设置和过滤设置进行渲染
            context.DrawRenderers(
                cullingResults, ref drawingSettings, ref filterSettings
            );
            context.DrawSkybox(camera);
        }
    }
}
